package com.whynot.frame.curtain.whynot.file.controller;


import com.whynot.frame.basic.file.MinioUtil;
import com.whynot.frame.basic.mybatis.conroller.BaseTableController;
import com.whynot.frame.basic.util.DateUtils;
import com.whynot.frame.basic.util.FileUtil;
import com.whynot.frame.basic.util.WebUtils;
import com.whynot.frame.curtain.whynot.file.entity.MediaFile;
import com.whynot.frame.curtain.whynot.file.entity.UploadResultVO;
import com.whynot.frame.curtain.whynot.file.service.MediaFileServiceImpl;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;

/**
 * <p>
 * 通用文件上传记录表 前端控制器
 * </p>
 *
 * @author zd
 * @since 2018-09-21
 */
@RestController
@Api(value = "mediaFile",description = "通用文件上传记录表接口")
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "请求已完成"),
        @ApiResponse(code = 201, message = "资源成功被创建"),
        @ApiResponse(code = 400, message = "请求中有语法问题，或不能满足请求"),
        @ApiResponse(code = 401, message = "未授权客户机访问数据"),
        @ApiResponse(code = 403, message = "服务器接受请求，但是拒绝处理"),
        @ApiResponse(code = 404, message = "服务器找不到给定的资源；文档不存在"),
        @ApiResponse(code = 500, message = "服务器出现异常")})
public class MediaFileController extends BaseTableController<MediaFileServiceImpl,MediaFile>
{
    private static final Logger logger = LoggerFactory.getLogger(MediaFileController.class);

    @Autowired
    private MediaFileServiceImpl baseService;

    @Autowired
    private MinioUtil minioUtil;

    @ApiOperation(value = "通用文件上传", notes = "通用文件上传", response = UploadResultVO.class)
    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public UploadResultVO upload(@RequestParam MultipartFile fileData, @ApiParam(name="catalogId",value="上传文件标识") @RequestParam(required = false) String catalogId){
        UploadResultVO urv = new UploadResultVO();
        if(!fileData.isEmpty()) {
            MediaFile mediaFile = new MediaFile();
            try {
                mediaFile.setCatalogId(catalogId);
                mediaFile.setFileName(FileUtil.newFileName(fileData.getOriginalFilename()));
                mediaFile.setFileOldName(fileData.getOriginalFilename());
                mediaFile.setFileSize(fileData.getSize());
                mediaFile.setBucketName(DateUtils.getCurrentDateAsString("yyyyMM"));
                mediaFile.setFileExt(FileUtil.getExtension(mediaFile.getFileOldName(),""));
                mediaFile.setContentType(fileData.getContentType());
                mediaFile.setIsDelete((byte) 0);
                //this.setCreateUser(mediaFile);
                mediaFile.setFileServerUrl(minioUtil.uploadStream(mediaFile.getBucketName(), mediaFile.getFileName(), fileData.getInputStream(), mediaFile.getContentType()));
                mediaFile.insert();
                urv.setFileId(mediaFile.getMediaId());
                urv.setSuccess(true);
                urv.setMsg("上传成功！");
            } catch (Exception e) {
                urv.setSuccess(false);
                urv.setMsg("上传失败");
                logger.error(e.getMessage(), e);
            }
        }else {
            urv.setSuccess(false);
            urv.setMsg("文件不存在");
        }
        return urv;
    }

    @ApiOperation(value = "通用文件下载", notes = "通用文件下载")
    @RequestMapping(value = "/download/{meidaId}",method = RequestMethod.GET)
    @ApiImplicitParam(name = "meidaId", value = "通用文件上传记录表ID", required = true, dataType = "String", paramType = "path")
    public void download(HttpServletRequest request, HttpServletResponse response, @PathVariable String meidaId)throws Exception{
        MediaFile mediaFile = new MediaFile().selectById(meidaId);
        if(mediaFile == null)
            throw new RuntimeException("文件不存在");
        WebUtils.download(response, minioUtil.getFileStream(mediaFile.getBucketName(), mediaFile.getFileName()), mediaFile.getFileOldName(), request);
    }

    @ApiOperation(value = "图片预览", notes = "图片预览")
    @RequestMapping(value = "/view/{meidaId}",method = RequestMethod.GET)
    @ApiImplicitParam(name = "meidaId", value = "通用文件上传记录表ID", required = true, dataType = "String", paramType = "path")
    public void view(HttpServletRequest request, HttpServletResponse response, @PathVariable String meidaId){
        MediaFile mediaFile = new MediaFile().selectById(meidaId);
        if(mediaFile == null)
            throw new RuntimeException("文件不存在");
        if(mediaFile.getContentType() != null && mediaFile.getContentType().startsWith("image/")){
            try {
                InputStream is = minioUtil.getFileStream(mediaFile.getBucketName(), mediaFile.getFileName());
                response.setContentType(mediaFile.getContentType());
                ServletOutputStream out = response.getOutputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                BufferedOutputStream bos = new BufferedOutputStream(out);
                byte[] buff = new byte[2048];
                int bytesRead;
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    bos.write(buff, 0, bytesRead);
                }
                bis.close();
                bos.close();
            }catch (Exception e){
                logger.error(e.getMessage(), e);
                throw new RuntimeException("文件不存在");
            }
        }else
            throw new RuntimeException("文件格式不支持预览！");
    }

    /*@ApiOperation(value = "根据文件标识获取文件列表", notes = "根据文件标识获取文件列表", response = APIBase.class)
    @RequestMapping(value = "/getfilelist/{catalogId}",method = RequestMethod.GET)
    @ApiImplicitParam(name = "catalogId", value = "文件标识", required = true, dataType = "String", paramType = "path")
    public APIBase getFilesByCatalogId(@PathVariable String catalogId){
        Map<String, Object> param = new HashMap<>();
        param.put("catalogId", catalogId);
        param.put("sort","CREATE_TIME");
        return new APIBase().setData(this.baseService.baseListQuery(param));
    }

    @ApiOperation(value = "分页查询通用文件上传记录表列表", notes = "符合前端UI数据格式", response = APIBase.class)
    @RequestMapping(value = "/getpagelist",method = RequestMethod.GET)
    public APIBase getPageList(@RequestParam Map<String, Object> param){
        Page page = new Page<MediaFile>();
        page.setCurrent(Optional.ofNullable(param.get("page")).map(value->Integer.valueOf(value.toString().trim())).orElse(1));
        page.setSize(Optional.ofNullable(param.get("rows")).map(value->Integer.valueOf(value.toString().trim())).orElse(10));
        param.put("sort",Optional.ofNullable(param.get("sort")).map(value-> StringUtils.toDBPatternStr(value.toString().trim())).orElse(""));
        param.put("limit",(page.getCurrent() - 1)*page.getSize() + "," + page.getSize());
        page.setTotal(this.baseService.baseCountQuery(param));
        page.setRecords(this.baseService.baseListQuery(param));
        return new APIBase().setData(page);
    }

    @ApiOperation(value = "根据主键ID获取通用文件上传记录表信息", notes = "根据主键ID获取通用文件上传记录表信息", response = APIBase.class)
    @RequestMapping(value = "/getfileinfo/{id}",method = RequestMethod.GET)
    @ApiImplicitParam(name = "id", value = "通用文件上传记录表ID", required = true, dataType = "String", paramType = "path")
    public APIBase getfileinfo(@PathVariable String id){
        MediaFile mediaFile = new MediaFile();
        return new APIBase().setData(mediaFile.selectById(id));
    }

    @ApiOperation(value = "根据文件ID逻辑删除文件", notes = "根据文件ID逻辑删除文件", response = APIBase.class)
    @RequestMapping(value = "/delete/{id}",method = RequestMethod.POST)
    @ApiImplicitParam(name = "id", value = "文件ID", required = true, dataType = "String", paramType = "path")
    public APIBase remove(@PathVariable String id){
        MediaFile mediaFile = new MediaFile();
        mediaFile.setMediaId(id);
        //this.setUpdateUser(mediaFile);
        mediaFile.setIsDelete((byte) 1);
        mediaFile.updateById();
        return new APIBase().setRSP();
    }

    @ApiOperation(value = "根据文件ID逻辑删除文件", notes = "根据文件ID逻辑删除文件", response = APIBase.class)
    @RequestMapping(value = "/deleteall/{catalogId}",method = RequestMethod.POST)
    public APIBase removeByCatalogId(@PathVariable String catalogId){
        MediaFile mediaFile = new MediaFile();
        //this.setUpdateUser(mediaFile);
        mediaFile.setIsDelete((byte) 1);
        EntityWrapper<MediaFile> ew = new EntityWrapper<>();
        ew.eq(MybatisUtil.getColumn("catalogId", MediaFile.class), catalogId);
        ew.eq(MybatisUtil.getColumn("isDelete", MediaFile.class), 0);
        mediaFile.update(ew);
        return new APIBase().setRSP();
    }*/
}
